希望這是 Functor 系列最後一篇了,來小試身手一下看你對 Functor 的掌控度 (鐵人賽結束後會回來加題數)
const nextCharForNumberString_ = str => {
const trimmed = str.trim()
const number = parseInt(trimmed)
const nextNumber = number + 1;
return String.fromCharCode(nextNumber)
}
const result = nextCharForNumberString_(' 64'); // 'A'
也許你會想到 Composition ,但 parseInt
、number+1
是無法直接用的,必須先包裝成 Function (算是一種作弊方法)。
const trimmed = str => str.trim()
const number = str => parseInt(str)
const nextNumber = num => num + 1
const nextCharForNumberString = num => String.fromCharCode(num)
const nextCharForNumberString = pipe(
trimmed,
number,
nextNumber,
nextCharForNumberString
)(' 64'); // 'A'
其實有另外一種方法,就是運用 Functor 把他包成 Box (data Type),而且 Functor 好處是就算 input 型別不同,但方法也可以共享 (因為已經先包成同樣 Type 的 Box 了 )
const Box = x => {
map: fn => Box(fn(x)),
fold: fn => fn(x) // 取值 remove from the box
}
const nextCharForNumberString = str =>
Box(str)
.map(x => x.trim())
.map(x => parseInt(x))
.map(x => x + 1)
.map(x => String.fromCharCode(x))
.fold(x => x)
const result = nextCharForNumberString(' 64'); // 'A'
因為 map
的參數是一個 function
,所以這個 function
要回傳任何東西都可以
x.trim() // method
parseInt(x) // function
x + 1 // binary operator
String.fromCharCode(x) // Class function
用 Functor 概念寫程式,我們不是單純直接呼叫函式,而是給一個 Box,把所有運算都放在裡面。然後對 Box 說
Hey Box, call that function to me
比較一開始的 nextCharForNumberString_
跟後來改成 Functor 的 nextCharForNumberString
如有錯誤或需要改進的地方,拜託跟我說。
我會以最快速度修改,感謝您
O.S. 前幾篇真的是用生命在寫,每天都在熬夜啊 orz
倒數四天了,最大願望是可以睡滿 8 小時啊 T T
歡迎追蹤我的部落格,除了技術文也會分享一些在矽谷工作的甘苦。